home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / buttonfly / parser.y < prev    next >
Text File  |  1994-08-01  |  7KB  |  379 lines

  1. %{
  2. #include <stdio.h>
  3. #include "buttonfly.h"
  4. button_struct *current_button;
  5. extern button_struct *buttons_input;
  6. extern button_struct *selected;
  7.  
  8.  
  9. extern char *malloc(), *realloc();
  10. %}
  11.  
  12. %union
  13. {
  14.     button_struct *b;
  15.     popup_struct *p;
  16.     char *string;
  17. }
  18.  
  19. %start starting
  20.  
  21. /*
  22.  * These tokens are returned by the lexer (lexer.c) -- add more as
  23.  * needed, but be sure to change the dot_tokens and token_num arrays
  24.  * below and NUM_TOKENS in buttonfly.h
  25.  */
  26. %token <string> MENU POPUP COLOR BACKCOLOR HIGHCOLOR CD
  27.  
  28. %token <string> ACTION TITLE
  29. %type <b> starting defaults default
  30. %type <b> buttons button
  31. %type <p> popup
  32. %type <string> commands command actions
  33.  
  34. %%
  35.  
  36. starting :
  37.         defaults buttons    { $$ = NULL; }
  38.     |   buttons { $$ = NULL; }
  39.     ;
  40.  
  41. defaults:    default   { $$ = NULL; }
  42.     |    defaults default    { $$ = NULL; }
  43.  
  44. default:    COLOR
  45.         {
  46.             do_color($1, selected->default_color, ".color.");
  47.             /*do_color($1, selected->color, ".color.");*/
  48.             $$ = NULL;
  49.         }
  50.     |    BACKCOLOR
  51.         {
  52.             do_color($1, selected->default_backcolor, ".backcolor.");
  53.             do_color($1, selected->backcolor, ".backcolor.");
  54.             $$ = NULL;
  55.         }
  56.     |    HIGHCOLOR
  57.         {
  58.             do_color($1, selected->default_highcolor, ".highcolor.");
  59.             /*do_color($1, selected->highcolor, ".highcolor.");*/
  60.             $$ = NULL;
  61.         }
  62.     |    popup
  63.         {
  64.             if (selected->popup == NULL)
  65.                 selected->popup = $1;
  66.             else
  67.             {
  68.                 $1->next = selected->popup;
  69.                 selected->popup = $1;
  70.             }
  71.             $$ = NULL;
  72.         }
  73.     |    actions
  74.         {
  75.             fprintf(stderr, "\ncough, gasp, ack, pbht!\n");
  76. fprintf(stderr, "buttonfly: can't put an action before a button in a menu file.\n");
  77.             $$ = NULL;
  78.         }
  79.     ;
  80.  
  81. buttons :    button
  82.         {
  83.             buttons_input = $1 ;
  84.             $$ = $1;
  85.         }
  86.     |    buttons button
  87.         {
  88.             $2->next = $1;
  89.             buttons_input = $2 ;
  90.             $$ = $2;
  91.         }
  92.     |    error
  93.         {
  94.             buttons_input = NULL;
  95.             $$ = NULL;
  96.         }
  97.     ;
  98.  
  99. button :    TITLE
  100.         {
  101.             /* Create a 'button' structure here */
  102.             current_button = new_button($1);
  103.             $<b>$ = current_button;
  104.         }
  105.         commands
  106.         {
  107.             /* Commands all add to current_button's structure */
  108.             $$ = $<b>2;
  109.         }
  110.     ;
  111.  
  112. commands : command
  113.     |    commands command    { $$ = NULL; }
  114.     ;
  115.  
  116. command : actions
  117.         {
  118.             if (current_button->action == NULL)
  119.             {    /* No actions before... */
  120.                 current_button->action = $1;
  121.             }
  122.             else if ($1 != NULL)
  123.             {    /* Add to list of actions */
  124.                 char *cat_strings();
  125.                 cat_strings(current_button->action,    ";");
  126.                 cat_strings(current_button->action, $1);
  127.             }
  128.             $$ = NULL;
  129.         }
  130.     |    MENU
  131.         {
  132.             if (current_button->submenu != NULL)
  133.             {
  134.                 fprintf(stderr, "Warning: two submenus specicied for");
  135.                 fprintf(stderr, " menu %s\n", current_button->name[0]);
  136.                 free(current_button->submenu);
  137.             }
  138.             current_button->submenu = strip($1);
  139.             $$ = NULL;
  140.         }
  141.     |    COLOR
  142.         {
  143.             do_color($1, current_button->color, ".color.");
  144.             $$ = NULL;
  145.         }
  146.     |    BACKCOLOR
  147.         {
  148.             do_color($1, current_button->backcolor, ".backcolor.");
  149.             $$ = NULL;
  150.         }
  151.     |    HIGHCOLOR
  152.         {
  153.             do_color($1, current_button->highcolor, ".highcolor.");
  154.             $$ = NULL;
  155.         }
  156.     |    CD
  157.         {
  158.             do_cd(current_button, $1);
  159.             $$ = NULL;
  160.         }
  161.     |    popup
  162.         {
  163.             if (current_button->popup == NULL)
  164.                 current_button->popup = $1;
  165.             else
  166.             {
  167.                 $1->next = current_button->popup;
  168.                 current_button->popup = $1;
  169.             }
  170.             $$ = NULL;
  171.         }
  172.     ;
  173.  
  174. popup :    POPUP actions
  175.         {
  176.             popup_struct *p;
  177.             p = (popup_struct *)malloc(sizeof(popup_struct));
  178.             p->title = $1 +1; /* +1 to account for space after .popup. */
  179.             p->action = $2;
  180.             p->next = NULL;
  181.             $$ = p;
  182.         }
  183.         ;
  184.  
  185. actions :    ACTION
  186.         {    /* Return a single string */
  187.             $$ = $1;
  188.         }
  189.     |    actions ACTION
  190.         {    /* Return strings separated by ';' */
  191.             char *t, *cat_strings();
  192.             t = cat_strings($1, ";");
  193.             t = cat_strings(t, $2);
  194.             free($2);
  195.             $$ = t;
  196.         }
  197.     |
  198.         {    /* Null action */
  199.             $$ = NULL;
  200.         }
  201.     ;
  202. %%
  203. /* Subroutines used by rules above */
  204.  
  205. /*
  206.  * If more .whatever. tokens are added, change the following two
  207.  * arrays, the %token <string> command below, and NUM_TOKENS in
  208.  * buttonfly.h
  209.  */
  210. int token_nums[NUM_TOKENS] =
  211. {
  212.     MENU,
  213.     POPUP, 
  214.     COLOR,
  215.     BACKCOLOR,
  216.     HIGHCOLOR,
  217.     CD, 
  218. };
  219. char *dot_tokens[NUM_TOKENS] =
  220. {
  221.     ".menu.",
  222.     ".popup.",
  223.     ".color.",
  224.     ".backcolor.",
  225.     ".highcolor.",
  226.     ".cd.",
  227. };
  228.  
  229. button_struct *new_button(s)
  230. char *s;
  231. {
  232.     button_struct *result;
  233.     int i;
  234.  
  235.     result = (button_struct *)malloc(sizeof(button_struct));
  236.     result->name[0][0] = '\0';
  237.     result->name[1][0] = '\0';
  238.     result->name[2][0] = '\0';
  239.     result->wc = 0;
  240.     find_words(0, s, result);
  241.     result->cwd = result->action = result->submenu = NULL;
  242.     result->popup = NULL;
  243.     if (selected) for (i=0; i<3; i++) {
  244.         result->color[i] = selected->default_color[i];
  245.         result->backcolor[i] = selected->default_backcolor[i];
  246.         result->highcolor[i] = selected->default_highcolor[i];
  247.         result->default_color[i] = selected->default_color[i];
  248.         result->default_backcolor[i] = selected->default_backcolor[i];
  249.         result->default_highcolor[i] = selected->default_highcolor[i];
  250.     } else for (i=0; i<3; i++) {
  251.         result->color[i] = 0.7;
  252.         result->highcolor[i] = 1.0;
  253.         result->backcolor[i] = 0.0;
  254.         result->default_color[i] = 0.7;
  255.         result->default_highcolor[i] = 1.0;
  256.         result->default_backcolor[i] = 0.0;
  257.     }
  258.     result->next = result->forward = NULL;
  259.     return result;
  260. }
  261.  
  262. void
  263. free_button(b)
  264. button_struct *b;
  265. {
  266.     if (b->cwd != NULL) free(b->cwd);
  267.     free(b);
  268. }
  269.  
  270. char *cat_strings(s1, s2)
  271. char *s1, *s2;
  272. {
  273.     s1 = realloc(s1, strlen(s1)+strlen(s2)+1);
  274.     strcat(s1, s2);
  275.     return s1;
  276. }
  277.  
  278. /*
  279.  *    Strip of leading and trailing spaces and tabs
  280.  */
  281. char *
  282. strip(s)
  283. char *s;
  284. {
  285.     int i, j;
  286.     
  287.     /* Ok, handle beginning of string */
  288.     if ((i = strspn(s, " \t")) != 0)
  289.     {
  290.         for (j = i; j < (strlen(s)+1); j++)
  291.             s[j-i] = s[j];
  292.     }
  293.     /* Now handle end */
  294.     for (i = strlen(s); i > 0; i--)
  295.     {
  296.         if (s[i] == ' ' || s[i] == '\t')
  297.             s[i] = '\0';
  298.         else
  299.             break;
  300.     }
  301.     return s;
  302. }
  303.  
  304. yyerror()
  305. {
  306.     /* In case of error... be quiet.
  307.      *    fprintf(stderr, "Syntax Error\n");
  308.      */
  309. }
  310.  
  311. find_words(n, str, button)
  312. int n;
  313. char *str;
  314. button_struct *button;
  315. {
  316.     int i;
  317.  
  318.     button->wc++;
  319.     if (strlen(str)<WORDLENGTH+1)
  320.     {
  321.         strcpy(button->name[n], str);
  322.     } 
  323.     else
  324.     {
  325.         i=WORDLENGTH+1;
  326.         while ((--i)>0 && str[i]!=' ');
  327.         if (i)
  328.         {
  329.             strncpy(button->name[n], str, i);
  330.             button->name[n][i]=0;
  331.             strcpy(str, str+i+1);
  332.             if (n<2) find_words(n+1, str, button);
  333.         }
  334.         else
  335.         {
  336.             strncpy(button->name[n], str, WORDLENGTH);
  337.             button->name[n][WORDLENGTH]=0;
  338.             if (n<2)
  339.             {
  340.                 for (i=WORDLENGTH; str[i]!=' ' && str[i]; i++);
  341.                 if (i<strlen(str))
  342.                 {
  343.                     strcpy(str, str+i+1);
  344.                     find_words(n+1, str, button);
  345.                 }
  346.             }
  347.         }
  348.     }
  349. }
  350.  
  351.  
  352. do_color(s, c, e)
  353. char *s;
  354. float *c;
  355. char *e;
  356. {
  357.     float r, g, b;
  358.  
  359.     if (sscanf(s, "%f %f %f", &r, &g, &b) != 3) {
  360.  
  361.     fprintf(stderr, "buttonfly: syntax error: %s\n", e);
  362.  
  363.     } else {
  364.  
  365.     c[0] = r;
  366.     c[1] = g;
  367.     c[2] = b;
  368.     }
  369. }
  370.  
  371. do_cd(b, str)
  372. button_struct *b;
  373. char *str;
  374. {
  375.     str = strip(str);
  376.     b->cwd = malloc(strlen(str)+1);
  377.     strcpy(b->cwd, str);
  378. }
  379.